package 多线程.案例.myBlockingQueue;

public class MyBlockingQueue {
    //简单实现阻塞队列
    int[] item = new int[100];  //队列
    static final int N = 10;   //队列的容量

    //队头和队尾
    int front = 0;
    int rear = 0;
    int curSize = 0; //当前元素个数

    //向阻塞队列里面放置元素, 一个线程如果阻塞了, 可以靠另一个线程唤醒
    public void put(int value) throws InterruptedException {
        synchronized (this) {
            while (isFull()) { //如果元素个数满了, 那就等待
                this.wait();   //被唤醒后再进行一次判断, 防止多线程的随机性引起bug
            }
            item[rear] = value;
            rear++;
            if (rear == N) {
                rear = 0;
            }
            curSize ++;
            this.notify(); //唤醒线程
        }
    }

    //向阻塞队列中取出元素
    public int take() throws InterruptedException {
        int value = 0;
        synchronized (this) {
            while (isEmpty()) { //如果没有元素
                this.wait();
            }
            value = item[front];
            front ++;
            if (front == N) {
                front = 0;
            }
            curSize --;
            this.notify();
        }
        return value;
    }

    //判断队列是否满了
    private boolean isFull() {
        return curSize == N;
    }

    //判断队列是否为空
    private boolean isEmpty() {
        return curSize == 0;
    }
}

